package com.mrd.gtimp.order.action;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.mrd.constant.HgDataConstants;
import com.mrd.constant.MsgConstants;
import com.mrd.exception.QueryException;
import com.mrd.exception.SaveException;
import com.mrd.exception.validation.MRDValidationException;
import com.mrd.framework.config.web.json.Result;
import com.mrd.framework.ui.Jqgrid;
import com.mrd.framework.ui.filter.SearchRule;
import com.mrd.framework.ui.filter.SearchRuleOption;
import com.mrd.framework.utils.HttpUtils;
import com.mrd.gtimp.base.entity.Company;
import com.mrd.gtimp.business.entity.Commodity;
import com.mrd.gtimp.business.entity.ContractTerms;
import com.mrd.gtimp.business.entity.Declaration;
import com.mrd.gtimp.business.entity.DeclarationAttachment;
import com.mrd.gtimp.business.entity.GoodsCode;
import com.mrd.gtimp.business.entity.SuiFuDan;
import com.mrd.gtimp.business.service.CompanyQpTempBiz;
import com.mrd.gtimp.business.service.ContractTermsBiz;
import com.mrd.gtimp.business.service.DeclarationAttachmentBiz;
import com.mrd.gtimp.business.service.DeclarationBiz;
import com.mrd.gtimp.business.service.DeclarationFreeBiz;
import com.mrd.gtimp.business.service.DeclarationPortBiz;
import com.mrd.gtimp.business.service.FundFlowBiz;
import com.mrd.gtimp.business.service.GoodsCodeBiz;
import com.mrd.gtimp.business.service.HgDataBiz;
import com.mrd.gtimp.business.service.PaymentABCBiz;
import com.mrd.gtimp.business.service.SuiFuDanBiz;
import com.mrd.gtimp.fix.ChnToCodeFix;
import com.mrd.gtimp.order.entity.DeclaContainer;
import com.mrd.gtimp.order.service.DeclaContainerBiz;
import com.mrd.gtimp.v2.datalock.DataLockUtil;
import com.mrd.gtimpframe.entity.CompanyInfo;
import com.mrd.gtimpframe.entity.CustomCompanyInfo;
import com.mrd.gtimpframe.entity.DeclaRelastionship;
import com.mrd.gtimpframe.entity.RejectCount;
import com.mrd.gtimpframe.repository.CusInfoMapper;
import com.mrd.gtimpframe.service.*;
import com.mrd.redis.JedisClientClusterImpl;
import com.mrd.util.FreeMarkerUtils;
import com.mrd.util.GtimpBusinessUtil;
import com.mrd.util.LoginUtil;
import com.mrd.util.ValidationUtil;

import org.activiti.engine.RuntimeService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.propertyeditors.StringTrimmerEditor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Created by lenovo on 2016/9/5. 在线下单
 */
@Controller
@RequestMapping("/order")
public class OrderAction {

    private static final Logger logger = LoggerFactory.getLogger(OrderAction.class);
    /**
     * 页面操作状态存储的变量名(操作状态,insert,update)
     */
    public static final String OPSTATE_STRING = "opState";

    /**
     * 一般贸易，加工贸易状态存储的变量名()
     */
    public static final String TRADETYPE_STRING = "tradeType";
    /**
     * 柜模板路径配置
     */
    @Value("${excel_container_model}")
    private String containerExcelTemplatePath;
    /**
     * 出口报关单模板路径配置
     */
    @Value("${excel_export_declaration_model}")
    private String exportDeclarationExcelTemplatePath;
    /**
     * 进口报关单模块路径配置
     */
    @Value("${excel_import_declaration_model}")
    private String importDeclarationExcelTemplatePath;
    @Resource
    private DeclarationBiz declarationBiz;
    @Resource
    private HgDataBiz hgDataBiz;
    @Resource
    private PaymentABCBiz paymentABCBiz;
    @Resource
    private DeclaContainerBiz declaContainerBiz;
    @Resource
    private ContractTermsBiz contractTermsBiz;
    @Resource
    private OriginalDeclarationBiz originalDeclarationBiz;
    @Resource
    private DeclaRelastionshipService declaRelastionshipService;
    @Resource
    private RejectCountService rejectCountService;
    @Resource
    private JedisClientClusterImpl jedisClientCluster;
    @Resource
    private DeclarationAttachmentBiz declarationAttachmentBiz;
    @Resource
    private DataLockUtil dataLockUtil;
    @Resource
    private CompanyInfoService companyInfoService;
    /**
     * 下单页面
     */
    public static final String ORDER_DECLARE_PAGE = "/order";
    /**
     * 下单详情页面
     */
    private static final String ORDER_DECLARE_PAGE_DETAIL = "gtimp/order/customsDetail";
    @Resource
    private DeclarationFreeBiz declarationFreeBiz;
    @Resource
    private SuiFuDanBiz suifuDanBiz;
    @Resource
    private GoodsCodeBiz goodsCodeBiz;
    @Autowired
    public ChnToCodeFix chnToCodeFix;
    @Resource
    private DeclarationPortBiz declarationPortBiz;
    @Resource
    private CompanyService companyService;

    @InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.registerCustomEditor(String.class, new StringTrimmerEditor(true)); // 处理提交到后台的空值
    }

    @RequestMapping("/test")
    public String test(Model model) {
        Declaration declaration = new Declaration();
        FreeMarkerUtils.prepareUseForFTL(declaration);
        model.addAttribute("declaration", declaration);

        // model.addAttribute("type", Declaration.DECLARATION_TYPE_ENTRY);
        model.addAttribute("type", Declaration.DECLARATION_TYPE_EXPORT);

        declaration.setTradeType(Declaration.TRADE_TYPE_GENERAL);
        // declaration.setTradeType(Declaration.TRADE_TYPE_Process);
        // declaration.setTradeType(Declaration.TRADE_TYPE_Special);
        /* return "/test-order"; */
        return "/test-order";
    }

    @RequestMapping("/ft")
    public String ft(Model model, String type, String tradeType) {
        Declaration declaration = new Declaration();
        // 设置贸易类型
        if (StringUtils.isNotEmpty(tradeType)) {
            declaration.setTradeType(tradeType);
        } else {
            declaration.setTradeType(Declaration.TRADE_TYPE_GENERAL);
        }
        FreeMarkerUtils.prepareUseForFTL(declaration);
        String isCCI = HttpUtils.getParam("isCCI");
        if (isCCI != null) {
            declaration.setIsTongguanYth(isCCI);
        } else {
            declaration.setIsTongguanYth("0");
        }
        model.addAttribute("declaration", declaration);
        if (Declaration.DECLARATION_TYPE_ENTRY.equals(type)) {
            model.addAttribute("type", Declaration.DECLARATION_TYPE_ENTRY);
        } else {
            model.addAttribute("type", Declaration.DECLARATION_TYPE_EXPORT);
        }
        boolean isSupplier = false;
        try {
            isSupplier = "CC".equals(LoginUtil.getLoginUser().getCompany().getType());
        } catch (Exception e1) {
            e1.printStackTrace();
        }
        model.addAttribute("isSupplier", isSupplier + "");
        model.addAttribute(OPSTATE_STRING, OperatioState.insert);
        model.addAttribute("soState", false);
        //return "/order";
        return "/order";
    }

    // /**
    // * 进口下单页面
    // */
    // @RequestMapping("/in")
    // public String inDeclare(Model model, String tradeType) {
    // return ft(model, Declaration.DECLARATION_TYPE_ENTRY, tradeType);
    // }

    /**
     * 进口下单页面 - 一般贸易
     */
    @RequestMapping("/in/general")
    public String inDeclareGeneral(Model model) {
        return ft(model, Declaration.DECLARATION_TYPE_ENTRY, Declaration.TRADE_TYPE_GENERAL);
    }

    /**
     * 进口下单页面 - 一般贸易
     */
    @RequestMapping("/in/process")
    public String inDeclareProcess(Model model) {
        return ft(model, Declaration.DECLARATION_TYPE_ENTRY, Declaration.TRADE_TYPE_Process);
    }

    /**
     * 进口下单页面 - 一般贸易
     */
    @RequestMapping("/in/special")
    public String inDeclareSpecial(Model model) {
        return ft(model, Declaration.DECLARATION_TYPE_ENTRY, Declaration.TRADE_TYPE_Special);
    }

    // /**
    // * 出口下单页面
    // */
    // @RequestMapping("/out")
    // public String outDeclare(Model model, String tradeType) {
    // return ft(model, Declaration.DECLARATION_TYPE_EXPORT, tradeType);
    // }

    /**
     * 出口下单页面 - 一般贸易
     */
    @RequestMapping("/out/general")
    public String outDeclareGeneral(Model model) {
        return ft(model, Declaration.DECLARATION_TYPE_EXPORT, Declaration.TRADE_TYPE_GENERAL);
    }

    /**
     * 出口下单页面 - 加工贸易
     */
    @RequestMapping("/out/process")
    public String outDeclare(Model model) {
        return ft(model, Declaration.DECLARATION_TYPE_EXPORT, Declaration.TRADE_TYPE_Process);
    }



    /**
     * 上传报关单数据对象，更新数据对象缓存，用于跳转报关单修改提交页面
     *
     * @return 报关单修改提交页面地址
     */
    @RequestMapping("/getExcelModel")
    @ResponseBody
    public Result getExcelModel(@RequestParam String d, @RequestParam String dt, @RequestParam String dtt) {
        // 验证报关单类型dt
        if (!"E".equals(dt) && !"I".equals(dt)) {
            String msg = "提交参数错误，F操作失败.";
            logger.error(String.format("%s,%s,%s", msg, d, dt));
            return Result.newFailInstance(msg);
        }
        Map<String, String> declarationCfgMap = new HashMap<String, String>() {
            {
                put("export_port", "出口口岸");
                put("buyer", "买方");
                put("company_name", "收发货人");
                put("fahuo_company_name", "生产销售单位");
                put("seller", "收发货人");
                put("bl_no", "提运单号");
                put("company_co", "收发货人代码");
                put("fahuo_company_co", "生产销售单位代码");
                put("transport_na", "运输工具名称");
                put("arrived_country", "运抵国");
                put("arrived_port", "指运港");
                put("goods_addr", "境内货源地");
                put("trading_country", "贸易国");
                put("deal_mode", "成交方式");
                put("goods_count", "件数");
                put("contract_no", "合同协议号");
                put("invoice_no", "合同协议号");
                put("goods_package", "包装种类");
                put("gross_weight", "毛重");
                put("net_weight", "净重");
                put("trade_mode", "监管方式");
                put("transport_mode", "运输方式");
                put("levymode", "征免性质");
                put("record_id", "备案号");
                put("license_no", "许可证号");
                // put("commodities","商品数据");
                put("special_relationship_confirm", "特殊关系确认");
                put("price_impact_confirm", "价格影响确认");
                put("payment_royaltils_confirm", "支付特许权使用费确认");
                // put("container_no", "柜号");
                put("other_goods_addr", "其他货源地");
                put("declaration_port", "申报口岸");
                put("supCompany", "报关行");
                put("remark", "备注");
            }
        };
        String commodityKey = "商品数据";
        Map<String, String> commodityCfgMap = new HashMap<String, String>() {
            {
                put("index_num", "项号");
                put("name", "商品名称");
                put("goods_mode", "规格型号");
                put("count", "数量");
                put("unit", "单位");
                put("destination", "最终目的国");
                put("unit_price", "单价");
                put("total_price", "总价");
                put("currency", "币种");
                put("levymode", "征免");
                put("code_t", "商品编号");
                put("origin_country", "原产国");
                put("record_id", "手册备案序号");
            }
        };
        String zxCommodityKey = "装箱商品数据";
        Map<String, String> zxCommodityCfgMap = new HashMap<String, String>() {
            {
                put("goods_net_weight", "净重");
                put("goods_number", "包装件数");
                put("package_type", "包装种类");
                put("goods_gross_weight", "毛重");
            }
        };
        String containerKey = "集装箱数据";
        Map<String, String> containerCfgMap = new HashMap<String, String>() {
            {
                put("containerNo", "集装箱号");
                put("containerStandard", "集装箱规格");
            }
        };

        try {
            JSONObject jobj = JSON.parseObject(d);
            // 报关单json数据类型校验，数据类型不对[提示用户 让他修改再导入]
            // json转declaration
            // json转commoditys
            // json转containers
            // set declaration into session
            // return SUCCESS(报关单修改提交页面地址)
            Declaration od = new Declaration();
            for (String key : declarationCfgMap.keySet()) {
                try {
                    Field f = null;
                    if (key.equalsIgnoreCase("supCompany")) {
                        List<Object> r = hgDataBiz.findObjectBySql(String.format("select com_id,com_name from T_SYS_COMPANY d where d.com_name=:name"), 1, 1, new HashMap<String, Object>() {
                            {
                                put("name", jobj.get(declarationCfgMap.get(key)).toString());
                            }
                        });
                        if (r.size() > 0) {
                            Object[] obj = (Object[]) r.get(0);
                            Company supCompany = new Company();
                            supCompany.setId(obj[0].toString());
                            supCompany.setName(obj[1].toString());
                            od.setSupCompany(supCompany);
                        }
                    } else {
                        f = od.getClass().getDeclaredField(key);
                        f.setAccessible(true);
                        f.set(od, jobj.get(declarationCfgMap.get(key)).toString());
                    }

                    // if("container_no".equals(f.getName())) {
                    // Field cf = od.getClass().getDeclaredField("container_no_show");
                    // cf.setAccessible(true);
                    // cf.set(od, jobj.get(declarationCfgMap.get(key)).toString());
                    // }
                    if (f.getName().equals("export_port")) {
                        List<Object> r = hgDataBiz.findObjectBySql(String.format("select code from cdams_qp_hgdata d where d.name=:name and d.type='%s'", HgDataConstants.HG_CUSTOMS_TYPE), 1, 1, new HashMap<String, Object>() {
                            {
                                put("name", jobj.get(declarationCfgMap.get(key)).toString());
                            }
                        });
                        if (r.size() > 0) {
                            Field f2 = od.getClass().getDeclaredField("export_port_code");
                            f2.setAccessible(true);
                            f2.set(od, r.get(0).toString());
                        }
                    }
                    if (f.getName().equals("arrived_country")) {
                        List<Object> r = hgDataBiz.findObjectBySql(String.format("select code from cdams_qp_hgdata d where d.name=:name and d.type='%s'", HgDataConstants.HG_COUNTRY_TYPE), 1, 1, new HashMap<String, Object>() {
                            {
                                put("name", jobj.get(declarationCfgMap.get(key)).toString());
                            }
                        });
                        if (r.size() > 0) {
                            Field f2 = od.getClass().getDeclaredField("arrived_country_code");
                            f2.setAccessible(true);
                            f2.set(od, r.get(0).toString());
                        }
                    }
                    if (f.getName().equals("arrived_port")) {
                        List<Object> r = hgDataBiz.findObjectBySql(String.format("select code from cdams_qp_hgdata d where d.name=:name and d.type='%s'", HgDataConstants.HG_COUNTRY_TYPE), 1, 1, new HashMap<String, Object>() {
                            {
                                put("name", jobj.get(declarationCfgMap.get(key)).toString());
                            }
                        });
                        if (r.size() > 0) {
                            Field f2 = od.getClass().getDeclaredField("arrived_port_code");
                            f2.setAccessible(true);
                            f2.set(od, r.get(0).toString());
                        }
                    }
                    if (f.getName().equals("trading_country")) {
                        List<Object> r = hgDataBiz.findObjectBySql(String.format("select code from cdams_qp_hgdata d where d.name=:name and d.type='%s'", HgDataConstants.HG_COUNTRY_TYPE), 1, 1, new HashMap<String, Object>() {
                            {
                                put("name", jobj.get(declarationCfgMap.get(key)).toString());
                            }
                        });
                        if (r.size() > 0) {
                            Field f2 = od.getClass().getDeclaredField("trading_country_code");
                            f2.setAccessible(true);
                            f2.set(od, r.get(0).toString());
                        }
                    }
                    if (f.getName().equals("seller")) {
                        List<Object> r = hgDataBiz.findObjectBySql(String.format("select company_address,company_phone,company_fax from cdams_qp_companys d where d.company_name=:name"), 1, 1, new HashMap<String, Object>() {
                            {
                                put("name", jobj.get(declarationCfgMap.get(key)).toString().trim().replace("\n", ""));
                            }
                        });
                        if (r.size() > 0) {
                            Object[] ar = (Object[]) r.get(0);
                            Field f2 = od.getClass().getDeclaredField("seller_address");
                            f2.setAccessible(true);
                            f2.set(od, ar[0].toString());
                            Field f3 = od.getClass().getDeclaredField("seller_phone");
                            f3.setAccessible(true);
                            f3.set(od, ar[1].toString());
                            Field f4 = od.getClass().getDeclaredField("seller_address");
                            f4.setAccessible(true);
                            f4.set(od, ar[2].toString());
                        }
                    }
                    if (f.getName().equalsIgnoreCase("declaration_port")) {
                        List<Object> r = hgDataBiz.findObjectBySql(String.format("select code from cdams_qp_hgdata d where d.name=:name and d.type='%s'", HgDataConstants.HG_CUSTOMS_TYPE), 1, 1, new HashMap<String, Object>() {
                            {
                                put("name", jobj.get(declarationCfgMap.get(key)).toString());
                            }
                        });
                        if (r.size() > 0) {
                            Field f2 = od.getClass().getDeclaredField("declaration_port_code");
                            f2.setAccessible(true);
                            f2.set(od, r.get(0).toString());
                        }
                    }
                    if (f.getName().equalsIgnoreCase("goods_addr")) {
                        List<Object> r = hgDataBiz.findObjectBySql(String.format("select code from cdams_qp_hgdata d where d.name=:name and d.type='%s'", HgDataConstants.HG_DISTRICT_TYPE), 1, 1, new HashMap<String, Object>() {
                            {
                                put("name", jobj.get(declarationCfgMap.get(key)).toString());
                            }
                        });
                        if (r.size() > 0) {
                            Field f2 = od.getClass().getDeclaredField("goods_addr_code");
                            f2.setAccessible(true);
                            f2.set(od, r.get(0).toString());
                        }
                    }
                    if (f.getName().equalsIgnoreCase("other_goods_addr")) {
                        Field f2 = od.getClass().getDeclaredField("remark");
                        f2.setAccessible(true);
                        f2.set(od, (od.getRemark().isEmpty() ? "" : od.getRemark().trim() + "，") + "其他货源地：" + jobj.get(declarationCfgMap.get(key)).toString());
                    }
                } catch (Exception e1) {
                    String msg = "报关单数据转化失败。";
                    logger.error(String.format("%s:%s", key, msg), e1);
                }
            }

            List<DeclaContainer> declaContainerList = new ArrayList<>();
            String containerJsonFormat = "{\"CONTAINER_NO\":\"%s\",\"CT_SIZE\":\"%s\"}";
            List<String> containerJsonList = new ArrayList<>();
            List<String> containerNoList = new ArrayList<>();
            JSONArray containerObjs = jobj.getJSONArray(containerKey);
            for (int i = 0; i < containerObjs.size(); i++) {
                try {
                    Object obj = containerObjs.get(i);
                    JSONObject containerObj = (JSONObject) obj;
                    DeclaContainer container = new DeclaContainer();
                    for (String key : containerCfgMap.keySet()) {
                        try {
                            Field f = container.getClass().getDeclaredField(key);
                            f.setAccessible(true);
                            String value = containerObj.get(containerCfgMap.get(key)).toString();
                            if (key.equalsIgnoreCase("containerNo")) {
                                f.set(container, value);
                            }
                            if (key.equalsIgnoreCase("containerStandard")) {
                                if (value.equalsIgnoreCase("海运40尺普通")) {
                                    value = "L";
                                } else {
                                    value = "S";
                                }
                                f.set(container, value);
                            }
                        } catch (Exception ex) {
                            String msg = "集装箱数据转化失败。";
                            logger.error(String.format("%s:%s。", key, msg), ex);
                        }
                    }
                    containerNoList.add(container.getContainerNo());
                    containerJsonList.add(String.format(containerJsonFormat, container.getContainerNo(), container.getContainerStandard()));
                    container.setDeclaration(od);
                    declaContainerList.add(container);
                } catch (Exception e) {
                    String msg = "集装箱转化失败。";
                    logger.error(String.format("%s。", msg), e);
                }
            }
            od.setContainer_no(com.mrd.util.StringUtils.join(containerNoList.iterator(), ","));
            od.setContainer_no_show(String.format("[%s]", com.mrd.util.StringUtils.join(containerJsonList.iterator(), ",")));
            od.setDeclaContainers(declaContainerList);

            List<Commodity> commodities = new ArrayList<>();
            JSONArray spObjs = jobj.getJSONArray(commodityKey);
            JSONArray zxspObjs = jobj.getJSONArray(zxCommodityKey);
            for (int i = 0; i < spObjs.size(); i++) {
                try {
                    Object obj = spObjs.get(i);
                    JSONObject spJobj = (JSONObject) obj;
                    Object zxobj = zxspObjs.get(i);
                    JSONObject zxspJobj = (JSONObject) zxobj;
                    Commodity cd = new Commodity();
                    for (String key : commodityCfgMap.keySet()) {
                        try {
                            Field f = cd.getClass().getDeclaredField(key);
                            if (f.getName().equals("code_t")) {
                                String v = spJobj.get(commodityCfgMap.get(key)).toString();
                                if (null != v) {
                                    if (v.length() == 10) {
                                        f.setAccessible(true);
                                        f.set(cd, v.substring(0, 8));
                                        Field f2 = cd.getClass().getDeclaredField("code_s");
                                        f2.setAccessible(true);
                                        f2.set(cd, v.substring(8, 10));
                                    } else if (v.length() == 8) {
                                        f.setAccessible(true);
                                        f.set(cd, spJobj.get(commodityCfgMap.get(key)).toString());
                                        Field f2 = cd.getClass().getDeclaredField("code_s");
                                        f2.setAccessible(true);
                                        f2.set(cd, "00");
                                    }
                                }
                            } else {
                                f.setAccessible(true);
                                f.set(cd, spJobj.get(commodityCfgMap.get(key)).toString());
                            }
                        } catch (Exception e1) {
                            String msg = "商品数据转化失败。";
                            logger.error(String.format("%s:%s。", key, msg), e1);
                        }
                    }
                    for (String key : zxCommodityCfgMap.keySet()) {
                        try {
                            Field f = cd.getClass().getDeclaredField(key);
                            f.setAccessible(true);
                            f.set(cd, zxspJobj.get(zxCommodityCfgMap.get(key)).toString());
                        } catch (Exception e1) {
                            String msg = "装箱商品数据转化失败。";
                            logger.error(String.format("%s:%s。", key, msg), e1);
                        }
                    }
                    commodities.add(cd);
                } catch (Exception ex) {
                    String msg = "商品转化失败。";
                    logger.error(String.format("%s。", msg), ex);
                }
            }

            od.setCommodities(commodities);
            resolveExclCommoditySecondUint(commodities);
            od.setTradeType(dtt);
            chnToCodeFix.chnToCode(od);
            od.setActionChain(Declaration.ChainModel.userExcl, true);
            HttpUtils.getSession().setAttribute("OrderExcelModel_data", od);
            HttpUtils.getSession().setAttribute("OrderExcelModel_type", dt);
            return Result.newSuccessInstance(MsgConstants.OPERATION_SUCCESS);
        } catch (Exception e) {
            String msg = "excel内容无法识别，操作失败.";
            logger.error(String.format("%s,%s,%s", msg, d, dt), e);
            return Result.newFailInstance(msg);
        }
    }

    private void resolveExclCommoditySecondUint(List<Commodity> commos) {
        for (Commodity commo : commos) {
            try {
                GoodsCode goodsCode = goodsCodeBiz.findByCodet(commo.getCode_t());
                commo.setLegalUnitCode(goodsCode.getUNIT_1());
                commo.setSecondUnitCode(goodsCode.getUNIT_2());
            } catch (QueryException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 修改报关单
     */
    @RequestMapping(value = "/update")
    public String update(Model model, @RequestParam String id) {
        if (StringUtils.isEmpty(id)) {
            model.addAttribute("soState", false);
            Object declaration = HttpUtils.getSession().getAttribute("OrderExcelModel_data");
            if (declaration != null) {
                FreeMarkerUtils.prepareUseForFTL(declaration);
                model.addAttribute("declaration", declaration);
                model.addAttribute("type", HttpUtils.getSession().getAttribute("OrderExcelModel_type"));
                model.addAttribute(OPSTATE_STRING, OperatioState.update);
                return ORDER_DECLARE_PAGE;
            }
        }
        try {
            Declaration declaration = declarationBiz.findEntityById(id);
            declarationBiz.checkDeclareCanUpdate(declaration); // 非草稿状态不允许修改
            if (declaration != null) {
                dataLockUtil.lock("VDBS", id, LoginUtil.getLoginUser().getAccount() + LoginUtil.getLoginUser().getName());
                FreeMarkerUtils.prepareUseForFTL(declaration);
                model.addAttribute("declaration", declaration);
                model.addAttribute("type", declaration.getDeclaration_type());
                String portCode = declaration.getSupCompany().getPort_code();
                if (StringUtils.isNotEmpty(portCode)) {
                    boolean hasSO = declarationPortBiz.findHasSOByPortCode(portCode);
                    model.addAttribute("soState", hasSO);
                }
            }
            Declaration.sortCommidities(declaration);
            model.addAttribute(OPSTATE_STRING, OperatioState.update);
        } catch (Exception e) {
            logger.warn("不能修改已提交的单证!操作人：{},操作单证：{}", LoginUtil.getLoginAccount(), id);
            Declaration declaration = new Declaration();
            declaration.setTradeType(Declaration.TRADE_TYPE_GENERAL);
            FreeMarkerUtils.prepareUseForFTL(declaration);
            Declaration.sortCommidities(declaration);
            model.addAttribute("declaration", declaration);
        }
        return ORDER_DECLARE_PAGE;
    }

    /**
     * 复制报关单
     *
     * @param id 待复制的报关单id
     */
    @RequestMapping(value = "/copy")
    public String copy(Model model, String id) {
        try {
            Declaration declaration = declarationBiz.copyDeclaration(id);
            if (declaration != null) {
                declaration.setSo("");
                declaration.setReport_date(new Date());
                FreeMarkerUtils.prepareUseForFTL(declaration);
                model.addAttribute("declaration", declaration);
                model.addAttribute("type", declaration.getDeclaration_type());
                declaration.clearActionChain();
                declaration.setActionChain(Declaration.ChainModel.copy, true);
                String portCode = declaration.getSupCompany().getPort_code();
                if (StringUtils.isNotEmpty(portCode)) {
                    boolean hasSO = declarationPortBiz.findHasSOByPortCode(portCode);
                    model.addAttribute("soState", hasSO);
                } else {
                    model.addAttribute("soState", false);
                }
            }
            Declaration.sortCommidities(declaration);
            model.addAttribute(OPSTATE_STRING, OperatioState.insert);
        } catch (Exception e) {
            logger.warn("复制报关单失败，查询错误!操作人：{},操作单证：{}", LoginUtil.getLoginAccount(), id);
            Declaration declaration = new Declaration();
            declaration.setTradeType(Declaration.TRADE_TYPE_GENERAL);
            FreeMarkerUtils.prepareUseForFTL(declaration);
            Declaration.sortCommidities(declaration);
            model.addAttribute("declaration", declaration);
        }
        return ORDER_DECLARE_PAGE;
    }

    /**
     * 暂存
     *
     * @param declaration 报关单
     */
    @RequestMapping("/save")
    @ResponseBody
    public Result save(Declaration declaration) {
        try {
            String did = declaration.getId();
            //为录单客户添加标记，直接下单或代录单
            String comId= LoginUtil.getLoginUser().getCompany().getId();
            CompanyInfo companyInfo=(CompanyInfo) companyInfoService.selectByPrimaryKey(comId);
            String companyType="0";
            if(StringUtils.isNoneEmpty(companyInfo.getType(),companyInfo.getIsAgent(),companyInfo.getIsDrectCust())) {//根据逻辑判断
                if(companyInfo.getIsDrectCust().equals("1") & companyInfo.getType().equals("CL") && companyInfo.getIsAgent().equals("1")) {
                    companyType = "1";
                }
            }
            declaration.setEnter_type(companyType);

            if (jedisClientCluster.get("lock_decla_" + declaration.getId(), String.class) != null) {
                return Result.newFailInstance("报关单已被锁定，解锁前不能进行操作");
            }
            if (declaration.getActionChain() == null || !declaration.getActionChain().endsWith("s2")) {
                declaration.setActionChain(Declaration.ChainModel.save, true);
            }
            chnToCodeFix.chnToCode(declaration);
            ValidationUtil.validate(declaration);
            GtimpBusinessUtil.formatContainerListAsContainerNoAndContainerNoShow(declaration);
            // GtimpBusinessUtil.checkCommodityValidity(declaration);
            RejectCount rejectCount = rejectCountService.selectByDid(declaration.getId());
            DeclaRelastionship declaRelastionship = null;
            if (rejectCount != null) {
                declaration = declarationBiz.rejectToNew(declaration, rejectCount.getCount() + "");
                if (rejectCount.getCount() == 1) {
                    declaRelastionship = new DeclaRelastionship(did);
                } else {
                    declaRelastionship = declaRelastionshipService.selectByDeclaId(did);
                    declaRelastionship.setParent(did);
                }
            }
            Declaration d = declarationBiz.save(declaration);
            // 如果是驳回过的单，建立报关单关系谱
            if (rejectCount != null) {
                declaRelastionship.setNode(d.getId());
                declaRelastionshipService.insertSelective(declaRelastionship);
            }
            if (StringUtils.isNotEmpty(d.getId())) {
                ContractTerms contractTerms = contractTermsBiz.findEntityByDeclaration(d);
                if (contractTerms == null) {
                    contractTerms = new ContractTerms();
                    contractTerms.setDeclaration(d);
                    contractTerms.setContract_total_chn(d.getTotal_money());
                    contractTerms.setContract_total_en(d.getTotal_money());
                    contractTerms.setCurrency_chn(d.getCommodities().get(0).getCurrency());
                    contractTerms.setCurrency_en(d.getCommodities().get(0).getCurrency());
                    contractTerms.setPrice_terms_chn(d.getDeal_mode());
                    contractTerms.setPrice_terms_en(d.getDeal_mode());
                    contractTerms.setPacking_chn(d.getGoods_package());
                    contractTerms.setLoading_port_chn(d.getGoods_addr());
                    contractTerms.setDestination_port_chn(d.getCommodities().get(0).getDestination());
                    contractTerms.setShipping_marks_chn(d.getCarton());
                    contractTermsBiz.saveOrupdateEntity(contractTerms);
                    d.setContract_terms_type("1");
                    d.setContractTerms(contractTerms);
                    d = declarationBiz.save(d);
                }
            }
            return Result.newSuccessInstance("保存成功!", d.getId());
        } catch (MRDValidationException e) {
            String msg = e.getMessage();
            String[] mses = msg.split(",");
            List<String> msList = new ArrayList<>();
            for (String mse : mses) {
                if (mse != null) {
                    msList.add(mse.trim());
                }
            }
            return Result.newFailInstance("数据校验错误!", msList);
        } catch (Exception e) {
            logger.error("暂存报关单出现错误", e);
            return Result.newFailInstance(e.getMessage());
        }
    }

    /**
     * 2.0下单页面保存方法
     */
    public Result v20Save(Declaration declaration, String sfdTempId) {
        List<SuiFuDan> suiFuDanList = suifuDanBiz.findByTempId(sfdTempId);
        assert declaration != null;
        declaration.setSuiFuDans(suiFuDanList);
        declarationBiz.containerNoShowConvertToDeclaContainers(declaration);
        declaration.setDeclaration_type("E");
        declaration.setTradeType(StringUtils.isEmpty(declaration.getRe_record_id()) ? "0" : "1");
        declaration.setActionChain(Declaration.ChainModel.save, false);
        return save(declaration);
    }

    /**
     * 2.0下单页面保存方法
     */
    public Result v20Save(Declaration declaration) {
        List<SuiFuDan> suiFuDanList = suifuDanBiz.findByDeclaration(declaration);
        assert declaration != null;
        declaration.setSuiFuDans(suiFuDanList);
        declarationBiz.containerNoShowConvertToDeclaContainers(declaration);
        declaration.setDeclaration_type("E");
        declaration.setTradeType(StringUtils.isEmpty(declaration.getRe_record_id()) ? "0" : "1");
        declaration.setActionChain(Declaration.ChainModel.save, false);
        chnToCodeFix.chnToCode(declaration);
        return save(declaration);
    }

    /**
     * 2.0下单页面提交方法
     */
    public Result v20Submit(Declaration declaration) {
        List<SuiFuDan> suiFuDanList = suifuDanBiz.findByDeclaration(declaration);
        assert declaration != null;
        declaration.setSuiFuDans(suiFuDanList);
        declarationBiz.containerNoShowConvertToDeclaContainers(declaration);
        declaration.setDeclaration_type("E");
        declaration.setTradeType("0");
        declaration.setActionChain(Declaration.ChainModel.submit, false);
        declaration.setIsTongguanYth("0"); // 直航
        return submit(declaration);
    }

    @Resource
    private CompanyQpTempBiz companyQpTempBiz;

    /**
     * 提交报关单
     */
    @RequestMapping("/submit")
    @ResponseBody
    public Result submit(Declaration declaration) {
        try {
            String rs = companyQpTempBiz.queryCompanyState(declaration.getCompany_co(), declaration.getCompany_name());
            //为录单客户添加标记，直接下单或代录单
            String comId= LoginUtil.getLoginUser().getCompany().getId();
            CompanyInfo companyInfo=(CompanyInfo) companyInfoService.selectByPrimaryKey(comId);
            String companyType="0";
            if(StringUtils.isNoneEmpty(companyInfo.getType(),companyInfo.getIsAgent(),companyInfo.getIsDrectCust())) {//根据逻辑判断
                if(companyInfo.getIsDrectCust().equals("1") & companyInfo.getType().equals("CL") && companyInfo.getIsAgent().equals("1")) {
                    companyType = "1";
                }
            }
            declaration.setEnter_type(companyType);
            if (StringUtils.isNotEmpty(rs) && rs.equalsIgnoreCase("fail")) {
                return Result.newFailInstance("收发货人为未审核状态，请等待审核后再提交!");
            } else if (StringUtils.isNotEmpty(rs) && rs.equalsIgnoreCase("reset")) {
                return Result.newFailInstance("请重新选择收发货人后再提交!");
            } else if (StringUtils.isEmpty(rs) || rs.equalsIgnoreCase("error")) {
                return Result.newFailInstance("收发货人查询错误，请联系管理员!");
            }
            rs = companyQpTempBiz.queryCompanyState(declaration.getFahuo_company_co(), declaration.getFahuo_company_name());
            if (StringUtils.isNotEmpty(rs) && rs.equalsIgnoreCase("fail")) {
                return Result.newFailInstance((Declaration.DECLARATION_TYPE_EXPORT.equals(declaration.getDeclaration_type()) ? "生产销售单位" : "消费使用单位") + "为未审核状态，请等待审核后再提交!");
            } else if (StringUtils.isNotEmpty(rs) && rs.equalsIgnoreCase("reset")) {
                return Result.newFailInstance("请重新选择收发货人后再提交!");
            } else if (StringUtils.isEmpty(rs) || rs.equalsIgnoreCase("error")) {
                return Result.newFailInstance("收发货人查询错误，请联系管理员!");
            }
            if (declaration.getActionChain() == null || !declaration.getActionChain().endsWith("S2")) {
                declaration.setActionChain(Declaration.ChainModel.submit, true);
            }
            chnToCodeFix.chnToCode(declaration);
            GtimpBusinessUtil.checkDeclaration(declaration);
            GtimpBusinessUtil.formatContainerListAsContainerNoAndContainerNoShow(declaration);
            Declaration d = declarationBiz.submit(declaration);
            // 第一手资料备份
            // originalDeclarationBiz.saveDeclarationAsOriginal(d.getId());

            /**
             * 优化 第一手资料备份异步保存
             *
             * @descript 提交单据的时候上面保存完就可以直接返回给用户，第一手资料做异步保存就行
             * @author han
             */
            String userId = LoginUtil.getLoginUser().getId();
            new Thread() {
                @Override
                public void run() {
                    originalDeclarationBiz.saveDeclarationAsOriginalByDidiUser(d.getId(), userId);
                }
            }.start();

            return Result.newSuccessInstance("提交成功!", d.getId());
        } catch (Exception e) {
            logger.error("提交报关单出现错误", e);
            return Result.newFailInstance("数据校验错误!", e.getMessage());
        }
    }

    /**
     * 客户从驳回修改页面提交报关单
     */
    @RequestMapping("/customerRejectSubmit")
    @ResponseBody
    public Result customerRejectSubmit(Declaration declaration) throws Exception {
        declaration.setState(Declaration.DeclarationBusinessState.DRAFT_STATE);
        declaration.setPayment_type("0");
        declaration.setBusinessId(declarationBiz.newBusinessKey());
        List<String> properties = new ArrayList<>();
        properties.add("state");
        properties.add("payment_type");
        properties.add("businessId");
        declarationBiz.updateEntity(declaration, properties);
        declaration.setRejectContents(null);
        return submit(declaration);
    }

    /**
     * 报关单详情
     *
     * @param id 报关单id
     */
    @RequestMapping("/detail")
    public String detail(Model model, String id) {
        model.addAttribute(OPSTATE_STRING, OperatioState.read);
        try {
            Declaration declaration = declarationBiz.findEntityById(id);
            if (declaration != null) {
                dataLockUtil.lock("VDBS", id, LoginUtil.getLoginUser().getAccount() + LoginUtil.getLoginUser().getName());
                FreeMarkerUtils.prepareUseForFTL(declaration);
                model.addAttribute("declaration", declaration);
                String isCCI = declaration.getIsTongguanYth();
                boolean isSecondSup = StringUtils.isNotEmpty(isCCI) && "1".equals(isCCI) && LoginUtil.getLoginUser().getCompany().getId().equals(declaration.getSecondSupId());
                model.addAttribute("isSecondSup", isSecondSup);
                model.addAttribute("type", declaration.getDeclaration_type());
                Declaration.sortCommidities(declaration);
                String portCode = declaration.getSupCompany().getPort_code();
                if (StringUtils.isNotEmpty(portCode)) {
                    boolean hasSO = declarationPortBiz.findHasSOByPortCode(portCode);
                    model.addAttribute("soState", hasSO);
                }

                /*** 详情查询附件，如果有附件，前端按钮显示可点，不然灰色(han) **/
                Jqgrid jqgrid = new Jqgrid();
                jqgrid.addRule(new SearchRule("bill_no", SearchRuleOption.eq, id));
                jqgrid.addOrder(Sort.Direction.DESC, "ctime");
                Page<DeclarationAttachment> attachments = declarationAttachmentBiz.findByJqgrid(jqgrid);
                if (attachments.getContent() != null && attachments.getContent().size() > 0) {
                    model.addAttribute("attachState", true);
                }
                /*待审核状态下，判断当前用户所属是否是签约报关行*/
                if (com.mrd.gtimpframe.entity.Declaration.DeclarationBusinessState.ORDER_STATE.equals(declaration.getState())) {
                    boolean isSign = "1".equals(LoginUtil.getLoginUser().getCompany().getIsSignWS());
                    model.addAttribute("isSignWS", isSign);
                }
            }
        } catch (Exception e) {
            Declaration declaration = new Declaration();
            declaration.setTradeType(Declaration.TRADE_TYPE_GENERAL);
            FreeMarkerUtils.prepareUseForFTL(declaration);
            Declaration.sortCommidities(declaration);
            model.addAttribute("declaration", declaration);
        }
        boolean isSupplier = false;
        try {
            isSupplier = "CC".equals(LoginUtil.getLoginUser().getCompany().getType());
        } catch (Exception e1) {
            e1.printStackTrace();
        }
        model.addAttribute("isSupplier", isSupplier + "");
        return ORDER_DECLARE_PAGE;
    }

    @Resource
    private FundFlowBiz fundFlowBiz;

    /**
     * 进入结算页面
     *
     * @param id 待结算的报关单
     */
    @RequestMapping("/payPage1")
    public String pay(Model model, String id) {
        try {
            Declaration declaration = declarationBiz.fillPayFeeToDeclaration(id);
            List<Declaration> dcs = new ArrayList<>();
            dcs.add(declaration);
            model.addAttribute("declarations", dcs);
            model.addAttribute("sum_free", declaration.getDeclaration_free());
            model.addAttribute("pay_id", declaration.getDeclarationFree().getPay_id());
            model.addAttribute("balance", fundFlowBiz.findCurrentBalance(LoginUtil.getLoginUser().getCompany().getId()));
        } catch (Exception e) {
            logger.error("计算结算信息错误!", e);
            model.addAttribute("errorMessage", e.getMessage());
        }
        return "/gtimp/declaration/confirmPay";
    }

    @Resource
    private ChargingService chargingService;

    @RequestMapping("/payPage")
    public String pay1(Model model, String id) {
        try {
            Object[] returns = chargingService.calcDeclarationFee(id);
            model.addAttribute("chargingList", returns[1]);
            model.addAttribute("sum_fee", returns[2]);
            model.addAttribute("balance", fundFlowBiz.findCurrentBalance(LoginUtil.getLoginUser().getCompany().getId()));
            model.addAttribute("pay_id", returns[0]);
            com.mrd.gtimpframe.entity.Company supplier = companyService.selectSupplierByDecId(id);
            model.addAttribute("brokerPhone", supplier.getComPhone());
        } catch (Exception e) {
            logger.error("计算结算信息错误!", e);
            e.printStackTrace();
            model.addAttribute("errorMessage", e.getMessage());
        }
        return "/gtimpframe/payment/payment";
    }

    /**
     * 转到农行支付
     */
    @RequestMapping("/business-payMent")
    @ResponseBody
    public Map<String, Object> payMent(String pay_id, String paymentType) {
        try {
            return declarationBiz.didPayment(pay_id, paymentType);
        } catch (Exception e) {
            logger.error(e.getMessage());
            Map<String, Object> result = new HashMap<>();
            result.put("payMent", e.getMessage());
            return result;
        }
    }

    /**
     * 检查是否存在拼柜
     *
     * @param id         报关单号
     * @param containers 柜号清单，以","分格
     */
    @RequestMapping("/check-piece")
    @ResponseBody
    public String checkPieceContainer(String id, String containers) {
        if (StringUtils.isNoneEmpty(containers)) {
            return String.valueOf(declaContainerBiz.findLastSameContainerOrder(id, containers.split(",")));
        } else {
            return "0";
        }
    }

    @Resource
    private RuntimeService runtimeService;

    @RequestMapping("/activiti/delete/{processInstance}")
    @ResponseBody
    public Result deleteActiviti(@PathVariable("processInstance") String processInstance) {
        if (StringUtils.isEmpty(processInstance)) {
            return Result.newFailInstance("删除失败，流程实例id为空!");
        }
        try {
            runtimeService.deleteProcessInstance(processInstance, "平台删除!");
            return Result.newSuccessInstance("删除流程实例成功!");
        } catch (Exception e) {
            logger.error("删除流程实例失败!", e);
            return Result.newFailInstance("删除流程实例失败!");
        }
    }

    /**
     * 修改报关信息
     */
    @RequestMapping("/updateDeclaration")
    @ResponseBody
    public String updateDeclaration(Declaration declaration) {
        if (StringUtils.isNotEmpty(declaration.getId())) {
            try {
                if (StringUtils.isEmpty(declaration.getUnityNo())) {
                    declaration.setUnityNo(UUID.randomUUID().toString());
                }
                declarationBiz.saveOrupdateEntity(declaration);
            } catch (SaveException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * 下载柜模板
     */
    @RequestMapping("/download/excel_container")
    @ResponseBody
    public void downloadContainerTemplate(HttpServletRequest request, HttpServletResponse response) {
        String basePath = request.getServletContext().getRealPath("/");
        String downloadFilePath = basePath + containerExcelTemplatePath;
        download(request, response, downloadFilePath, "报关单柜列表模板");
    }

    /**
     * 下载出口报关单模板
     */
    @RequestMapping("/download/excel_export_declaration")
    @ResponseBody
    public void downloadExportDeclarationTemplate(HttpServletRequest request, HttpServletResponse response) {
        String basePath = request.getServletContext().getRealPath("/");
        String downloadFilePath = basePath + exportDeclarationExcelTemplatePath;
        download(request, response, downloadFilePath, "出口报关单模板");
    }

    /**
     * 下载进口报关单模板
     */
    @RequestMapping("/download/excel_import_declaration")
    @ResponseBody
    public void downloadImportDeclarationTemplate(HttpServletRequest request, HttpServletResponse response) {
        String basePath = request.getServletContext().getRealPath("/");
        String downloadFilePath = basePath + importDeclarationExcelTemplatePath;
        download(request, response, downloadFilePath, "进口报关单柜列表模板");
    }

    /**
     * 设置让浏览器弹出下载对话框的Header. 根据浏览器的不同设置不同的编码格式 防止中文乱码
     *
     * @param fileName 下载后的文件名.
     */
    private void download(HttpServletRequest request, HttpServletResponse response, String downloadFilePath, String fileName) {
        File downFiles = new File(downloadFilePath);
        if (!downFiles.exists()) {
            return;
        }
        if (!fileName.contains(".") && downloadFilePath.contains(".")) {
            fileName += downloadFilePath.substring(downloadFilePath.lastIndexOf("."));
        }
        try (InputStream fis = new FileInputStream(downFiles); BufferedInputStream bis = new BufferedInputStream(fis); OutputStream fos = response.getOutputStream(); BufferedOutputStream bos = new BufferedOutputStream(fos)) {
            // 中文文件名支持
            String encodedFileName;
            String agent = request.getHeader("USER-AGENT");
            if (agent != null && agent.contains("MSIE")) {// IE
                encodedFileName = java.net.URLEncoder.encode(fileName, "UTF-8");
            } else if (agent != null && agent.contains("Mozilla")) {
                encodedFileName = new String(fileName.getBytes("UTF-8"), "iso-8859-1");
            } else {
                encodedFileName = java.net.URLEncoder.encode(fileName, "UTF-8");
            }
            response.setHeader("Content-Disposition", "attachment; filename=\"" + encodedFileName + "\"");
            response.setHeader("Content-Length", "" + downFiles.length());
            int byteRead;
            byte[] buffer = new byte[2048];
            while ((byteRead = bis.read(buffer, 0, 2048)) != -1) {
                bos.write(buffer, 0, byteRead);
            }
            bos.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 未付款里面中的报关单提交
     *
     * @param id 报关单ID
     */
    @RequestMapping("unpaidMainSubmit")
    public String unpaidMainSubmit(Model model, String id) {
        String[] stateAndPayment = declarationBiz.getDeclarationStateAndPaymentType(id);
        String state = stateAndPayment[0];
        String paymentType = stateAndPayment[1];
        if (Declaration.DeclarationBusinessState.DRAFT_STATE.equals(state)) {
            return update(model, id);
        } else if ((Declaration.DeclarationBusinessState.ORDER_STATE.equals(state) || Declaration.DeclarationBusinessState.PASS_STATE.equals(state)) && "0".equals(paymentType)) {
            return pay(model, id);
        } else {
            //// TODO: 2016/11/18 其他处理
            return "error_page";
        }
    }

    @RequestMapping("/declarationToPdf")
    public String declarationBackupToPdf(Model model, String originalId) {
        Declaration declaration = originalDeclarationBiz.getDeclarationFromOriginalId(originalId);
        FreeMarkerUtils.prepareUseForFTL(declaration);
        model.addAttribute("declaration", declaration);
        if (Declaration.DECLARATION_TYPE_ENTRY.equals(declaration.getType())) {
            model.addAttribute("type", Declaration.DECLARATION_TYPE_ENTRY);
        } else {
            model.addAttribute("type", Declaration.DECLARATION_TYPE_EXPORT);
        }
        model.addAttribute(OPSTATE_STRING, OperatioState.insert);
        model.addAttribute("soState", false);
        model.addAttribute("pdfMode", true);
        return "/order";
    }

}


/**
 * 页面操作状态
 */
enum OperatioState {
    insert, update, read
}
